package com.mf.all.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.mf.all.constant.ConstantBasic;
import com.mf.all.emuns.enumsPublic.EnumPublicEnableOrDisable;
import com.mf.all.entity.dto.DtoMaterial;
import com.mf.all.entity.req.search.basic.SearchReqMaterial;
import com.mf.all.exception.GraceException;
import com.mf.all.mapper.MapperMaterial;
import com.mf.all.service.ServiceMaterial;
import com.mf.all.utils.UtilIdGenerator;
import com.mf.all.utils.UtilsEnum;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class ImplServiceMaterial extends ServiceImpl<MapperMaterial, DtoMaterial> implements ServiceMaterial {


    @Override
    public LambdaQueryWrapper<DtoMaterial> fillParams(SearchReqMaterial params) {
        final LambdaQueryWrapper<DtoMaterial> wr = loadQw();
        if (StringUtils.isNotBlank(params.getKey())) {
            wr.and(w -> {
                w.like(DtoMaterial::getCode, params.getKey())
                        .or()
                        .like(DtoMaterial::getMaName, params.getKey())
                        .or()
                        .like(DtoMaterial::getFullName, params.getKey());
            });
        }
        wr.eq(ObjectUtils.isNotEmpty(params.getPid()), DtoMaterial::getPid, params.getPid())
                .eq(StringUtils.isNotEmpty(params.getSize()), DtoMaterial::getSize, params.getSize())
                .eq(StringUtils.isNotBlank(params.getUnit()), DtoMaterial::getUnit, params.getUnit())
                .eq(ObjectUtils.isNotEmpty(params.getStatus()), DtoMaterial::getStatus, params.getStatus());

        wr.orderByDesc(DtoMaterial::getId)
                .orderByDesc(DtoMaterial::getSort);

        return wr;
    }

    /**
     * 修改
     */
    @Override
    @Transactional
    public void updateMaterialById(DtoMaterial dtoMaterial) {
        if (ObjectUtils.isNotEmpty(dtoMaterial.getPid()) && dtoMaterial.getPid() > 0) {
            Assert.state(ObjectUtils.isEmpty(getById(dtoMaterial.getPid())), "物料不存在");
        }
        dtoMaterial.setFullName(null);
        dtoMaterial.setCode(null);
        dtoMaterial.setMaName(null);
        setMaterialFullName(dtoMaterial);
        updateById(dtoMaterial);
    }

    /**
     * 修改状态
     */
    @Override
    public void updateStatusById(DtoMaterial dtoMaterial) {
        UtilsEnum.existsInEnum(EnumPublicEnableOrDisable.class, dtoMaterial.getStatus());
        final LambdaQueryWrapper<DtoMaterial> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DtoMaterial::getPid, dtoMaterial.getId())
                .eq(DtoMaterial::getStatus, EnumPublicEnableOrDisable.ENABLE.getCode());
        if (ObjectUtils.isNotEmpty(getOne(wrapper))) {
            GraceException.display("存在子级物料，不允许禁用");
        }
        updateById(dtoMaterial);
    }

    /**
     * 保存
     */
    @Override
    @Transactional
    public void saveMaterial(DtoMaterial dtoMaterial) {
        if (ObjectUtils.isNotEmpty(dtoMaterial.getPid()) && dtoMaterial.getPid() > 0) {
            Assert.state(ObjectUtils.isNotEmpty(getById(dtoMaterial.getPid())), "物料不存在");
        }

        final LambdaQueryWrapper<DtoMaterial> wrapper = loadQw();
        wrapper.orderByDesc(DtoMaterial::getId).last("limit 1");
        final DtoMaterial dtoMaterial1 = getOne(wrapper);
        if (ObjectUtils.isNotEmpty(dtoMaterial1)) {
            dtoMaterial.setCode(UtilIdGenerator.incrementId(dtoMaterial1.getCode()));
        } else {
            dtoMaterial.setCode(UtilIdGenerator.generateId("M_CODE", 6, 0));
        }


        setMaterialFullName(dtoMaterial);
        save(dtoMaterial);
    }

    /**
     * 设置物料全称
     */
    @Transactional
    public void setMaterialFullName(DtoMaterial dtoMaterial) {

        final LambdaQueryWrapper<DtoMaterial> wrapper = loadQw();
        wrapper.eq(DtoMaterial::getStatus, EnumPublicEnableOrDisable.ENABLE.getCode());
        final List<DtoMaterial> list = list(wrapper);
        //转换为map集合 key为id value为对应 DtoMaterial 数据
        final Map<Integer, DtoMaterial> dtoMaterialMap = list.stream().collect(Collectors.toMap(DtoMaterial::getId, DtoMaterial -> DtoMaterial));
        dtoMaterial.setFullName(getMaterialFullName(dtoMaterial, dtoMaterialMap));
    }

    /**
     * 获取物料全称
     */
    @Transactional
    public String getMaterialFullName(DtoMaterial dtoMaterial, Map<Integer, DtoMaterial> dtoMaterialMap) {
        String fullName = "";
        final Integer pid = dtoMaterial.getPid();
        if (pid != null && pid != 0) {
            final DtoMaterial dtoMaterial1 = dtoMaterialMap.get(pid);
            fullName = dtoMaterial1.getFullName();
            if (dtoMaterial1.getPid() != null && dtoMaterial1.getPid() != 0) {
                fullName = getMaterialFullName(dtoMaterial1, dtoMaterialMap) + "/" + fullName;
            }
        }
        return StringUtils.isNotBlank(fullName) ? fullName + "/" + dtoMaterial.getMaName() : dtoMaterial.getMaName();
    }

}